require 'puppet/acceptance/temp_file_utils'

extend Puppet::Acceptance::TempFileUtils
initialize_temp_dirs

teardown do
  remove_temp_dirs
end

test_name "CVE 2013-4761 Remote code execution via REST resource_type" do
  confine :except, :platform => 'windows'
  confine :except, :platform => /osx/ # see PUP-4820

  create_test_file(master, 'auth.conf', <<-AUTH)
path /resource_type
method find, search
auth any
allow *
  AUTH

  create_remote_file(master, '/tmp/exploit.rb', <<-EXPLOIT)
  ::File.open('/tmp/exploited', 'w') { |f| f.puts("exploited") }
  EXPLOIT
  chmod(master, '777', '/tmp/exploit.rb')

  master_opts = {
    'master' => {
      'autosign' => true,
      'rest_authconfig' => get_test_file_path(master, 'auth.conf'),
    },
  }

  with_puppet_running_on(master, master_opts) do
    # Ensure each agent has a signed cert
    on agents, puppet("agent", "-t", "--server #{master}")

    agents.each do |agent|
      next if agent['roles'].include?('master')

      step "Ensure that the exploit marker is gone" do
        on master, "rm -f /tmp/exploited"
      end

      step "Request a type that maps to the exploit file" do
        type_name = "::..::..::..::..::..::tmp::exploit"
        payload = "https://#{master}:8140/puppet/v3/resource_type/#{type_name}?environment=production"
        cert_path = on(agent, puppet("agent", "--configprint hostcert")).stdout.chomp
        key_path = on(agent, puppet("agent", "--configprint hostprivkey")).stdout.chomp
        curl_base = "curl --tlsv1 -g --cert \"#{cert_path}\" --key \"#{key_path}\" -k -H 'Accept: pson'"

        on agent, "#{curl_base} '#{payload}'"
      end

      step "Check that the exploit marker was not created" do
        on master, "test ! -e /tmp/exploited"
      end
    end
  end
end
